今天要來介紹的是元件的生命週期,了解生命週期才能在元件進行初始化和轉譯期間時執行額外的作業。
這邊先上流程圖,我們再來慢慢說明。
可以看到觸發變更的時間點有三個,父元件渲染到子元件時,使用者行為導致的事件產生,以及父元件將其從渲染樹移除。
而我們能覆寫的生命週期方法有以下四個:
OnInitialized
/ OnInitializedAsync
)此時間點上,元件已從父元件接收到初始化的參數,只會在 SetParametersAsync
完成後執行一次,絕對不會再次執行。
而當元件屬於頁面元件,也就是使用了 @page
變成可路由元件,如果 URL 不變 blazor 就會重新使用該元件,也就是不會執行 OnInitialized/OnInitializedAsync
且不會觸發 IDisposable.Dispose
。
OnParametersSet
/ OnParametersSetAsync
)此時間點上,元件已經初始化完成,當 OnInitialized/OnInitializedAsync
執行結束後會執行外,父元件重新渲染並提供新參數時,也會被呼叫。
提供新參數時如果是可變的類型,如自訂類型時,因為 blazor 無法知道參數的內部是否發生變化,所以一律視為已改變;但不可變的類型,則需要至少一個參數改變,才會重新渲染。
ShouldRender
)再提到 ShouldRender
之前,先提一下它上層的 StateHasChanged
,StateHasChanged
是不能異動的,用於通知元件其狀態已變更,且所有的 EventCallback
方法都會自動呼叫 StateHasChanged
。
如果想要避免使用者操作產生的渲染時,可以覆寫此方法來防止 UI 重新渲染,也就是可以確保渲染樹一定是從初始化產生的。
若想進一步了解可以參考ASP.NET Core Blazor WebAssembly 效能最佳做法 - 避免不必要的元件呈現。
OnAfterRender
/ OnAfterRenderAsync
)此時間點上,元件已經完成渲染。此時 DOM 就已經畫好了,如果要使用第三方的 JavaScript 來存取 DOM,就能正確取得了。
而這方法有提供 firstRender
參數,代表是否為第一次渲染,可以確保有些動作只在初始化時執行一次即可。
這邊要特別注意的是,如果在元件的生命週期中訂閱事件,請務必在元件移除時進行解除,可以透過實作 IDisposable
來正確釋放資源。
@implements IDisposable
...
@code {
private EventHandler<FieldChangedEventArgs> fieldChanged;
protected override void OnInitialized()
{
editContext = new EditContext(...);
fieldChanged = (_, __) =>
{
// ...
};
editContext.OnFieldChanged += fieldChanged;
}
public void Dispose()
{
editContext.OnFieldChanged -= fieldChanged;
}
}
以上就是元件生命週期的介紹,如果想看實際用法可以參考範例程式碼 - day13。
感謝大家的閱讀,我們明天見。
參考資料
ASP.NET Core Blazor 生命週期
Component lifecycles
使用 IDisposable 的元件處置